/**
 * Moondance UML modeling tool
 * 
 * @author Dascalu Laurentiu (dascalu.laurentziu@gmail.com).
 * 
 * This program is free software; you can redistribute it and
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 3
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package ro.pub.cs.se.moondance.xmi.deconverter;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.Iterator;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspace;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.ide.IDE;
import org.w3c.dom.Document;

import ro.pub.cs.se.moondance.MoondanceData;
import ro.pub.cs.se.moondance.UMLPageSerialized;
import ro.pub.cs.se.moondance.XMIPageSerializedReader;
import ro.pub.cs.se.moondance.model.UMLDiagram;

public class XMIDeconverter {
	// Singleton specific functions
	private static final XMIDeconverter INSTANCE = new XMIDeconverter();

	private XMIDeconverter() {

	}

	public static XMIDeconverter getInstance() {
		return INSTANCE;
	}

	public static void deconvertXMIFiles(Vector<String> fileNames,
			String projectName) {
		INSTANCE.setProjectName(projectName);
		for (Iterator<String> it = fileNames.iterator(); it.hasNext(); INSTANCE
				.xmiToMoondanceFormat(it.next()))
			;
	}

	// Class methods
	/**
	 * Transforms an UML diagram from XMI format into Moondance format. The
	 * purpose is to implement a communication way between UML modelers.
	 */
	public void xmiToMoondanceFormat(String fileName) {
		this.fileName = fileName;
		String newFileName = fileName.replaceAll(
				XMIPageSerializedReader.XMI_EXTENSION,
				UMLPageSerialized.DEFAULT_EXTENSION);

		ByteArrayOutputStream out = new ByteArrayOutputStream();
		try {
			createOutputStream(out);

			IWorkspace workspace = ResourcesPlugin.getWorkspace();
			workspace.getPathVariableManager().getPathVariableNames();
			IPath location = Path.fromOSString(newFileName);
			IProject project = workspace.getRoot().getProject(projectName);
			IFile newFile = project.getFile(location);

			if (newFile.exists())
				newFile.delete(true, MoondanceData.DEFAULT_MONITOR);

			newFile.create(new ByteArrayInputStream(out.toByteArray()), true,
					MoondanceData.DEFAULT_MONITOR);

			IWorkbenchPage page = MoondanceData.getWorkbench()
					.getActiveWorkbenchWindow().getActivePage();
			IDE.openEditor(page, newFile, true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	// Generated diagram
	private UMLDiagram diagram;

	// Selected project as destination for the import operation
	private String projectName;

	// Imported file name
	private String fileName;

	private void createOutputStream(OutputStream os) throws IOException {
		ObjectOutputStream oos = new ObjectOutputStream(os);
		XMIUMLDiagramDeconverter deconverter = new XMIUMLDiagramDeconverter();

		try {
			IWorkspace workspace = ResourcesPlugin.getWorkspace();
			workspace.getPathVariableManager().getPathVariableNames();
			IProject project = workspace.getRoot().getProject(projectName);
			IPath path = project.getLocation();
			File file = new File(path.toFile().getAbsolutePath() + "/"
					+ fileName);

			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = dbf.newDocumentBuilder();
			Document doc = db.parse(file);
			doc.getDocumentElement().normalize();
			diagram = deconverter.deconvert(doc.getDocumentElement());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		oos.writeObject(diagram);
		oos.close();
	}

	public void setProjectName(String projectName) {
		this.projectName = projectName;
	}

	public String getProjectName() {
		return projectName;
	}
}
